package http;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.cookie.CookieSpec;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.grlea.log.SimpleLogger;

import pattern.YahooPatterns;

public class HTTPConnection {
	private static final SimpleLogger log = new SimpleLogger(
			HTTPConnection.class);

	private static Map persistCookies = new HashMap(10);
	private static HTTPConnection conn = null;

	public static HTTPConnection getInstance() {
		if (conn != null) {
			return conn;
		} else {
			conn = new HTTPConnection();
		}
		return conn;
	}

	public static void main(String[] args) {
		URL url = null;
		try {
			url = new URL("http", "mail.yahoo.com", "");
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		HTTPConnection.getInstance().connect(url, null, "GET", "application/x-www-form-urlencoded");
	}

	public StringBuffer connect(URL url, NameValuePair[] requestParams, String requestMethod, String contentType) {
		try {
			HttpClient client = new HttpClient();
			client.getParams().setCookiePolicy(CookiePolicy.RFC_2109);
			client.getHostConfiguration().setHost(url.getHost(), url.getPort(),
					url.getProtocol());
			
			if(persistCookies != null){
				log.debug("using cookies persistent"+persistCookies.size());
				HttpState initialState = new HttpState();
				initialState.addCookies((Cookie[]) persistCookies.values().toArray(new Cookie[]{}));
				client.setState(initialState);
			}else{
				log.debug("no cookies persistent");
			}
			
			if ("POST".equalsIgnoreCase(requestMethod)) {
				PostMethod authpost = new PostMethod(url.toString());
				// Prepare login parameters
	        	authpost.addRequestHeader("User-Agent", YahooPatterns.UserAgent);
	        	authpost.addRequestHeader("Content-Type", contentType);
	        	if("application/x-www-form-urlencoded".equals(contentType)){
	        		authpost.setRequestBody(requestParams);
	        	}else{ // soap xml
	        		authpost.setRequestBody(requestParams[0].getValue());
	        	}
				client.executeMethod(authpost);
		        System.out.println("Login form post: " + authpost.getStatusLine().toString()); 
		        // release any connection resources used by the method
//		        authpost.releaseConnection();
		        
//		      See if we got any cookies
		        // The only way of telling whether logon succeeded is 
		        // by finding a session cookie

//		      See if we got any cookies
		        CookieSpec cookiespec = CookiePolicy.getDefaultSpec();
		        Cookie[] logoncookies = cookiespec.match(
		            url.getHost(), 80, "/", false, client.getState().getCookies());
//		        System.out.println("Logon cookies:");    
		        if (logoncookies.length == 0) {
//		            System.out.println("None");    
		        } else {
		            for (int i = 0; i < logoncookies.length; i++) {
//		                System.out.println("- " + logoncookies[i].toString());
		                persistCookies.put(logoncookies[i].getName(), logoncookies[i]);
		            }
		        }
		        
		        int statuscode = authpost.getStatusCode();
		        System.out.println("status code: " + statuscode);
		        if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) ||
		                (statuscode == HttpStatus.SC_MOVED_PERMANENTLY) ||
		                (statuscode == HttpStatus.SC_SEE_OTHER) ||
		                (statuscode == HttpStatus.SC_TEMPORARY_REDIRECT)) {
		                Header header = authpost.getResponseHeader("location");
		                if (header != null) {
		                    String newuri = header.getValue();
		                    if ((newuri == null) || (newuri.equals(""))) {
		                        newuri = "/";
		                    }
		                    System.out.println("Redirect target: " + newuri); 
		                    GetMethod redirect = new GetMethod(newuri);

		                    client.executeMethod(redirect);
//		                    System.out.println("Redirect: " + redirect.getStatusLine().toString()); 
		                    // release any connection resources used by the method
		                    StringBuffer sb = new StringBuffer(redirect.getResponseBodyAsString());
		                    redirect.releaseConnection();
		                    return sb;
		                } else {
		                    System.out.println("Invalid redirect");
//		                    System.exit(1);
		                }
		            }else{
		            	// there is no redirect!! so send the stream back..
	                    StringBuffer sb = new StringBuffer(authpost.getResponseBodyAsString());
	                    return sb;
		            }
		        }else{
		        	GetMethod authget = new GetMethod(url.toString());

		        	authget.addRequestHeader("User-Agent", YahooPatterns.UserAgent);
		        	authget.addRequestHeader("Content-Type", contentType);

		        	client.executeMethod(authget);
			        System.out.println("stauts line from get: " + authget.getStatusLine().toString());
//				      See if we got any cookies
			        CookieSpec cookiespec = CookiePolicy.getDefaultSpec();
			        Cookie[] logoncookies = cookiespec.match(
			            url.getHost(), 80, "/", false, client.getState().getCookies());
//			        System.out.println("Logon cookies:");    
			        if (logoncookies.length == 0) {
//			            System.out.println("None");    
			        } else {
			            for (int i = 0; i < logoncookies.length; i++) {
//			                System.out.println("- " + logoncookies[i].toString());
			                persistCookies.put(logoncookies[i].getName(), logoncookies[i]);
			            }
			        }

			        return new StringBuffer(authget.getResponseBodyAsString());
			}
		}
		catch (HttpException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}
